package com.puntodonna.fogliocassa.client.app.place.login;

import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.puntodonna.fogliocassa.client.place.NameTokens;
import com.gwtplatform.mvp.client.proxy.NotifyingAsyncCallback;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.google.inject.Inject;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;
import com.puntodonna.fogliocassa.client.action.LoginAction;
import com.puntodonna.fogliocassa.client.action.LoginActionResult;
import com.puntodonna.fogliocassa.client.app.presenter.header.HeaderPresenter;
import com.puntodonna.fogliocassa.client.app.presenter.main.MainPresenter;
import com.puntodonna.fogliocassa.shared.UserObj;

public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> {

	public interface MyView extends View {
		public TextBox getUserTextBox();

		public PasswordTextBox getPasswordTextBox();

		public Button getLoginBtn();
		
		public Button getCreateBtn();

		public void setMessage(String message);
	}

	@ProxyCodeSplit
	@NameToken(NameTokens.login)
	public interface MyProxy extends ProxyPlace<LoginPresenter> {
	}

	@Inject
	protected DispatchAsync dispatchAsync;

	@Inject
	protected PlaceManager placeManager;

	@Inject
	protected HeaderPresenter headerPresenter;

	protected UserObj userObj;

	@Inject
	public LoginPresenter(final EventBus eventBus, final MyView view, final MyProxy proxy) {
		super(eventBus, view, proxy);
	}

	protected void setup() {
		getView().getLoginBtn().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				String check = doCheck();
				String user = getView().getUserTextBox().getValue();
				String password = getView().getPasswordTextBox().getValue();
				if (check != null) {
					getView().setMessage(check);
					return;
				}
				
				NotifyingAsyncCallback<LoginActionResult> callback = getLoginAsyncCallback();
				callback.prepare();
				getDispatchAsync().execute(new LoginAction(user, password), callback);
				callback.checkLoading();
			}
		});
		
		getView().getCreateBtn().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				String check = doCheck();
				String user = getView().getUserTextBox().getValue();
				String password = getView().getPasswordTextBox().getValue();
				if (check != null) {
					getView().setMessage(check);
					return;
				}
				
				NotifyingAsyncCallback<LoginActionResult> callback = getLoginAsyncCallback();
				callback.prepare();
				getDispatchAsync().execute(new LoginAction(user, password, true), callback);
				callback.checkLoading();
			}
		});
	}
	
	protected String doCheck(){
		String user = getView().getUserTextBox().getValue();
		if (user.isEmpty()) {
			return "user: inserire un valore";
		}
		String password = getView().getPasswordTextBox().getValue();
		if (password.isEmpty()) {
			return "password: inserire un valore";
		}
		return null;
	}

	@Override
	protected void revealInParent() {
		RevealContentEvent.fire(this, MainPresenter.TYPE_WIDGET_AREA, this);
	}

	@Override
	protected void onBind() {
		super.onBind();
		setup();
	}

	@Override
	protected void onReset() {
		super.onReset();
		getHeaderPresenter().getView().getInfoPanel().setVisible(false);
	}

	protected NotifyingAsyncCallback<LoginActionResult> getLoginAsyncCallback() {
		return new NotifyingAsyncCallback<LoginActionResult>(getEventBus()) {

			@Override
			protected void success(LoginActionResult result) {
				try {
					if (result.isLoggedIn()) {
						setUserObj(result.getUserObj());
						getHeaderPresenter().setUserObject(result.getUserObj());
						getHeaderPresenter().getView().getInfoPanel().setVisible(true);
						getPlaceManager().revealPlace(new PlaceRequest(NameTokens.getFogliocassa()), false);
					} else {
						getView().setMessage(result.getResult());
					}
				} catch (Exception e) {
					GWT.log("PersistanceAction failed (client side)!", e);
					Window.alert("PersistanceAction failed (client side)!\r\n" + e);
				}
			}

			@Override
			protected void failure(Throwable caught) {
				GWT.log("PersistanceAction failed (server side)!", caught);
				Window.alert("PersistanceAction failed (server side)!\r\n" + caught);
			}

		};
	}

	public HeaderPresenter getHeaderPresenter() {
		return headerPresenter;
	}

	public DispatchAsync getDispatchAsync() {
		return dispatchAsync;
	}

	public PlaceManager getPlaceManager() {
		return placeManager;
	}

	public UserObj getUserObj() {
		return userObj;
	}

	protected void setUserObj(UserObj userObj) {
		this.userObj = userObj;
	}
}
